/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.web.gwt.form.client.widget.item.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.genia.toolbox.web.gwt.basics.client.GwtHelper;
import com.genia.toolbox.web.gwt.basics.client.bean.GwtLocale;
import com.genia.toolbox.web.gwt.basics.client.i18n.GwtI18nMessage;
import com.genia.toolbox.web.gwt.basics.client.widget.AbstractI18nTextBoxBase;
import com.genia.toolbox.web.gwt.form.client.CssNames;
import com.genia.toolbox.web.gwt.form.client.form.SimpleItem;
import com.genia.toolbox.web.gwt.form.client.widget.item.ItemWidgetModifyListener;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBoxBase;
import com.google.gwt.user.client.ui.Widget;

/**
 * the implementation of <code>SimpleItemWidget</code> for a
 * <code>I18nTextBoxBaseItem</code>.
 * 
 * @param <ITEM>
 *          the type of item handled by this widget.
 */
public abstract class AbstractI18nTextBoxBaseItemWidget<ITEM extends SimpleItem>
    extends AbstractSimpleItemWidget<ITEM>
{
  /**
   * the delimiter of language and textBoxBase text.
   */
  private final static String DELIM = "::";

  /**
   * the main panel of the <code>Composite</code>.
   */
  private final transient HorizontalPanel hPanel = new HorizontalPanel();

  /**
   * the list of all the <code>Widget</code> that must be modify to update the
   * error message.
   */
  private final transient Widget[] widgetsToToggle;

  /**
   * the TextBoxBase encapsulated in this SimpleItemWidget.
   */
  private final transient AbstractI18nTextBoxBase i18nTextBoxBase;



  /**
   * contructor.
   * 
   * @param cssName
   *          the specific css name to add to the widget
   * @param item
   *          the item this object represents.
   */
  public AbstractI18nTextBoxBaseItemWidget(final String cssName, final ITEM item)
  {
    super(item);
    i18nTextBoxBase = getI18nTextBoxBase();
    widgetsToToggle = new Widget[] { i18nTextBoxBase, hPanel };

    // get the properties of a TextBoxItem.
    final GwtI18nMessage tBoxLabel = item.getLabelKey();

    final Label labelWidget = new Label();

    // set the text to the labelWidget.
    GwtHelper.fillText(labelWidget, tBoxLabel);

    // add styleName to the panel.
    hPanel.addStyleName(CssNames.I18N_TEXTBOXBASE_WIDGET_CSS_STYLE);
    hPanel.addStyleName(cssName);
    hPanel.addStyleName(item.getName());

    // add the widget to the panel.
    hPanel.add(labelWidget);
    hPanel.add(i18nTextBoxBase);

    initWidget(hPanel);
  }



  /**
   * returns the I18nTextBoxBase encapsulated in this SimpleItemWidget.
   * 
   * @return the I18nTextBoxBase encapsulated in this SimpleItemWidget
   */
  protected abstract AbstractI18nTextBoxBase getI18nTextBoxBase();



  /**
   * getter for the widgetsToToggle property.
   * 
   * @return the widgetsToToggle
   */
  @Override
  protected Widget[] getWidgetsToToggle()
  {
    return widgetsToToggle;
  }



  /**
   * returns the current value of the <code>I18nTextBoxBase</code>.
   * 
   * @return the current value of the <code>I18nTextBoxBase</code>
   */
  public List<String> getValues()
  {
    final List<String> res = new ArrayList<String>();

    for (Entry<GwtLocale, TextBoxBase> entry : i18nTextBoxBase.getWidgetsByLocale().entrySet()) {
      String s = entry.getKey().getStringRepresentation();
      String textValue = entry.getValue().getText();
      if (textValue == null) {
        textValue = "";
      }
      s += DELIM + textValue;
      res.add(s);
    }
    if (res.isEmpty()) {
      return null;
    }

    return res;
  }



  /**
   * set the current values of the <code>I18nTextBoxBase</code>.
   * 
   * @param values
   *          the current values of the <code>I18nTextBoxBase</code>
   */
  public void setValues(final List<String> values)
  {
    i18nTextBoxBase.executeCommand(new Command()
    {
      public void execute()
      {
        Map<GwtLocale, TextBoxBase> widgetsByLocale = i18nTextBoxBase.getWidgetsByLocale();
        if (values == null) {
          for (final GwtLocale gwtLocale : widgetsByLocale.keySet()) {
            widgetsByLocale.get(gwtLocale).setText(null);
          }
        }
        else {
          for (final GwtLocale gwtLocale : widgetsByLocale.keySet()) {
            TextBoxBase textBoxBase = widgetsByLocale.get(gwtLocale);
            for (final String value : values) {
              final int delimIndex = value.indexOf(DELIM);
              if (delimIndex >= 0) {
                String languageRepresentation = value.substring(0, delimIndex);
                if (gwtLocale.getStringRepresentation().equalsIgnoreCase(languageRepresentation)) {
                  textBoxBase.setText(value.substring(delimIndex + DELIM.length()));
                }
              }
            }
          }
        }
      }
    });

  }



  /**
   * add a listener that is called each time the value of this object change.
   * 
   * @param modifyListener
   *          the callback
   */
  public void addModifyListener(final ItemWidgetModifyListener modifyListener)
  {
    i18nTextBoxBase.addChangeListener(new ChangeListener()
    {

      public void onChange(final Widget widget)
      {
        modifyListener.onModify(AbstractI18nTextBoxBaseItemWidget.this);
      }

    });

    i18nTextBoxBase.addKeyboardListener(new KeyboardListenerAdapter()
    {

      @Override
      public void onKeyUp(final Widget widget, final char key, final int modifier)
      {
        modifyListener.onModify(AbstractI18nTextBoxBaseItemWidget.this);
      }

    });

  }

}
